/**
 * 将对象的键名从大驼峰转换为小驼峰格式
 * @example
 * toLowerCamelCase({ FirstName: 'John' }) // { firstName: 'John' }
 */
export function toLowerCamelCase<T extends Record<string, any>>(obj: T): Record<string, any> {
  if (!obj || typeof obj !== 'object' && !Array.isArray(obj)) return obj;

  if (Array.isArray(obj)) {
    return obj.map(item => toLowerCamelCase(item));
  }

  return Object.entries(obj).reduce((acc, [key, value]) => {
    const newKey = key.charAt(0).toLowerCase() + key.slice(1);
    const newValue = value && typeof value === 'object' ? toLowerCamelCase(value) : value;
    acc[newKey] = newValue;
    return acc;
  }, {} as Record<string, any>);
}

/**
 * 将字符串转换为大驼峰格式
 * @example
 * toPascalCase('verificationCode') // 'VerificationCode'
 * toPascalCase('verification_code') // 'VerificationCode'
 */
function toPascalCase(str: string): string {
  // 处理下划线格式
  if (str.includes('_')) {
    return str
      .split('_')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
      .join('');
  }

  // 处理小驼峰格式
  return str
    .split(/(?=[A-Z])/)
    .map((word, index) =>
      index === 0
        ? word.charAt(0).toUpperCase() + word.slice(1)
        : word
    )
    .join('');
}

/**
 * 将对象的键名转换为大驼峰格式
 * @example
 * toUpperCamelCase({ verificationCode: '123' }) // { VerificationCode: '123' }
 */
export function toUpperCamelCase<T extends Record<string, any>>(obj: T): Record<string, any> {
  if (!obj || typeof obj !== 'object' && !Array.isArray(obj)) return obj;

  if (Array.isArray(obj)) {
    return obj.map(item => toUpperCamelCase(item));
  }

  return Object.entries(obj).reduce((acc, [key, value]) => {
    const newKey = toPascalCase(key);
    const newValue = value && typeof value === 'object' ? toUpperCamelCase(value) : value;
    acc[newKey] = newValue;
    return acc;
  }, {} as Record<string, any>);
}
